import numpy as np


# 创建用户-物品评分矩阵
def create_ratings_matrix():
    ratings_matrix = np.array([
        [5, 4, 0, 4, 2, 0],
        [0, 2, 4, 0, 5, 0],
        [2, 0, 0, 1, 4, 3],
        [4, 0, 3, 5, 1, 2],
        [0, 3, 0, 2, 0, 5],
        [1, 0, 5, 0, 3, 0]
    ])
    return ratings_matrix


# 计算用户之间的相似度
def calculate_similarity(ratings_matrix):
    num_users = ratings_matrix.shape[0]
    # 创建一个num_users维的0矩阵
    similarity_matrix = np.zeros((num_users, num_users))
    for i in range(num_users):
        for j in range(num_users):
            if i != j:
                # 计算余弦相似度
                dot_product = np.dot(ratings_matrix[i], ratings_matrix[j])
                norm_i = np.linalg.norm(ratings_matrix[i])
                norm_j = np.linalg.norm(ratings_matrix[j])
                similarity_matrix[i, j] = dot_product / (norm_i * norm_j)
    return similarity_matrix


# 预测指定用户对指定物品的评分
def predict_rating(ratings_matrix, similarity_matrix, user_id, item_id):
    num_users = ratings_matrix.shape[0]

    numerator = 0
    denominator = 0
    for i in range(num_users):
        if i != user_id and ratings_matrix[i, item_id] != 0:  # 仅考虑其他用户对该物品有评分的情况
            similarity = similarity_matrix[user_id, i]
            numerator += similarity * ratings_matrix[i, item_id]
            denominator += np.abs(similarity)

    if denominator != 0:
        predicted_rating = numerator / denominator
    else:
        predicted_rating = 0

    return predicted_rating


if __name__ == '__main__':
    # 示例评分矩阵
    ratings = create_ratings_matrix()

    # 计算用户之间的相似度
    similarity = calculate_similarity(ratings)

    # 预测用户1对物品2的评分
    user_id = 1
    item_id = 2
    predicted_rating = predict_rating(ratings, similarity, user_id, item_id)

    print(f"预测用户{user_id}对物品{item_id}的评分: {predicted_rating:.2f}")
